package com.jbookshelf.dal.providers;

import java.util.ArrayList;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.hibernate.criterion.CriteriaSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


import com.jbookshelf.dal.entities.Books;
import com.jbookshelf.dal.entities.BooksGenres;

@Repository
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public class BooksDataProviderImp implements BooksDataProvider {

	@Autowired
	SessionFactory sessionFactory;
	
	@Override
	@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
	public List<Books> getBooks() {
		Session s = sessionFactory.getCurrentSession();
		Criteria cr = s.createCriteria(Books.class);
		cr.createAlias("authors", "fullNames", CriteriaSpecification.LEFT_JOIN);
		return cr.list();

	}

	@Override
	@Transactional(readOnly=true, propagation=Propagation.SUPPORTS, rollbackFor=Exception.class)
	public List<Books> getBooksByAuthor(String author) {
		Session session = sessionFactory.getCurrentSession();
		Query query  = session.createQuery("from Books b where b.authors.fullName = :author" );
		query.setString("author", author);
		return query.list();
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
	public void saveBook(Books book) {
        Session s = sessionFactory.getCurrentSession();
        s.save(book);
		
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
	public List<Books> getBooksByGenres(String genres) {
        Session s = sessionFactory.getCurrentSession();
        Query q  = s.createQuery("from Books b ");
        List<Books> books = new ArrayList<Books>();
        Iterator<Books> booksIterator = q.list().iterator();
        while (booksIterator.hasNext()){
            Books book = booksIterator.next();
            if(book.getBooksGenreses().contains(genres))
                  books.add(book);
        }
        return books;
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
	public Books getBookByName(String bookName) {
		Session session = sessionFactory.getCurrentSession();
        Query query  = session.createQuery("from Books where name = :bookname ");
        query.setString("bookname", bookName);
        Books book = (Books)query.uniqueResult();
        return book;
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
	public List<String> getISBNlist() {
		Session session = sessionFactory.getCurrentSession();
        Query query  = session.createQuery("select isbn from Books");
        return query.list();
	}


}
